package com.menghao.batch.config;

import com.menghao.batch.entity.file.XmlCar;
import com.menghao.batch.entity.file.XmlUser;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.xml.builder.StaxEventItemReaderBuilder;
import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.xstream.XStreamMarshaller;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>XML批处理配置.<br>
 *
 * @author menghao.
 * @version 2018/4/2.
 */
@Configuration
public class XmlBatchConfig {

    private final StepBuilderFactory stepBuilderFactory;

    private final JobBuilderFactory jobBuilderFactory;

    @Autowired
    public XmlBatchConfig(StepBuilderFactory stepBuilderFactory, JobBuilderFactory jobBuilderFactory) {
        this.stepBuilderFactory = stepBuilderFactory;
        this.jobBuilderFactory = jobBuilderFactory;
    }

    @Bean
    public XStreamMarshaller xStreamMarshaller() {
        XStreamMarshaller xStreamMarshaller = new XStreamMarshaller();
        xStreamMarshaller.setAnnotatedClasses(XmlUser.class);
        // 与注解方式择其一
        xStreamMarshaller.setAliases(new HashMap<String, String>(1) {{
            put("xml-user", XmlUser.class.getName());
        }});
        // 与注解方式择其一
        xStreamMarshaller.setFieldAliases(new HashMap<String, String>(1) {{
            put(XmlUser.class.getName() + ".xmlCar", "xml-car");
        }});
        return xStreamMarshaller;
    }

    @Bean
    public ItemReader<XmlUser> xmlItemReader(XStreamMarshaller xStreamMarshaller) {
        return new StaxEventItemReaderBuilder<XmlUser>()
                .name("xmlItemReader")
                .resource(new ClassPathResource("before.xml"))
                .addFragmentRootElements("xml-user")
                .unmarshaller(xStreamMarshaller)
                .build();
    }

    @Bean
    public ItemWriter<XmlUser> xmlItemWriter(XStreamMarshaller xStreamMarshaller) {
        return new StaxEventItemWriterBuilder<XmlUser>()
                .name("xmlItemWriter")
                .resource(new ClassPathResource("after.xml"))
                .marshaller(xStreamMarshaller)
                .build();
    }

    @Bean
    public Step xmlStep(ItemReader<XmlUser> xmlItemReader,
                        ItemWriter<XmlUser> xmlItemWriter) {
        return stepBuilderFactory.get("xmlStep")
                .<XmlUser, XmlUser>chunk(5)
                .reader(xmlItemReader)
                .processor((ItemProcessor<XmlUser, XmlUser>) batchUser -> {
                    batchUser.setAge(batchUser.getAge() + 1);
                    batchUser.setDescription("已处理");
                    return batchUser;
                })
                .writer(xmlItemWriter)
                .build();
    }

    @Bean
    public Job xmlJob(Step xmlStep) {
        return jobBuilderFactory.get("xmlJob")
                .incrementer(new RunIdIncrementer())
                .start(xmlStep)
                .build();
    }
}
